﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="BaseModel.cs" company="">
//   
// </copyright>
// <summary>
//   The side.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace RescueRaiders.Models
{
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Audio;
    using Microsoft.Xna.Framework.Graphics;
    using System;
    using RescueRaiders.Properties;

    /// <summary>
    /// The side.
    /// </summary>
    internal enum Side
    {
        /// <summary>
        /// The none.
        /// </summary>
        None,

        /// <summary>
        /// The player 1.
        /// </summary>
        Player1,

        /// <summary>
        /// The player 2.
        /// </summary>
        Player2
    }

    /// <summary>
    /// The base model.
    /// </summary>
    internal abstract class BaseModel
    {
        #region Public class members

        /// <summary>
        /// The location of the center of the sprite
        /// In screen coordinates
        /// </summary>
        public Vector2 CenterPosition
        {
            get
            {
                return Position + Center;
            }
        }

        /// <summary>
        /// Gets CollisionMatrix.
        /// </summary>
        public Matrix CollisionMatrix
        {
            get
            {
                return Procedures.Transform(Center, Rotation, Position);
            }
        }

        /// <summary>
        /// Gets Emitter.
        /// </summary>
        public AudioEmitter Emitter { get; private set; }

        /// <summary>
        /// size of the frame
        /// </summary>
        public Point frameSize { get; set; }

        /// <summary>
        /// The location of the sprite
        /// In screen coordinates
        /// </summary>
        public Vector2 Position { get; protected set; }

        /// <summary>
        /// The side of the model,
        /// True = player's side, False = computer's side
        /// </summary>
        public Side Side { get; private set; }

        /// <summary>
        /// Gets or sets Texturedata.
        /// </summary>
        public Color[] Texturedata { get; set; }

        /// <summary>
        /// The location of the center of the sprite, around which Rotation should happen
        /// In frame coordinates
        /// </summary>
        protected Vector2 Center { get; set; }

        /// <summary>
        /// Gets IsFlip.
        /// </summary>
        protected virtual SpriteEffects IsFlip
        {
            get
            {
                return SpriteEffects.None;
            }
        }

        /// <summary>
        /// Gets or sets Rotation.
        /// </summary>
        protected virtual float Rotation { get; set; }

        /// <summary>
        /// Gets SourceRectangle.
        /// </summary>
        protected virtual Rectangle? SourceRectangle
        {
            get
            {
                return null;
            }
        }

        public Rectangle PosRectangle
        {
            get
            {
                var z = (int)Math.Sqrt((frameSize.X * frameSize.X) + (frameSize.Y * frameSize.Y));
                return new Rectangle ((int) Position.X,(int)  Position.Y, z, z);
            }
        }

        /// <summary>
        /// The texture of the sprite
        /// </summary>
        protected Texture2D Texture { get; private set; }

        #endregion

        #region Constructor

        /// <summary>
        /// Initializes a new instance of the <see cref="BaseModel"/> class.
        /// </summary>
        /// <param name="texture">
        /// The texture.
        /// </param>
        /// <param name="position">
        /// The position.
        /// </param>
        /// <param name="side">
        /// The side.
        /// </param>
        protected BaseModel(Texture2D texture, Vector2 position, Side side)
        {
            Texture = texture;
            Position = position;
            Side = side;
            Emitter = new AudioEmitter();
        }

        #endregion

        #region Public methods

        /// <summary>
        /// The draw.
        /// </summary>
        /// <param name="spriteBatch">
        /// The sprite batch.
        /// </param>
        /// <param name="cameraX">
        /// The camera x.
        /// </param>
        public virtual void Draw(SpriteBatch spriteBatch, float cameraX)
        {
            var positionInView = new Vector2(Position.X - cameraX, Position.Y);
            spriteBatch.Draw(
                Texture, positionInView, SourceRectangle, Color.White, Rotation, Center, 1.0f, IsFlip, 0.6f);
        }

        /// <summary>
        /// The drawradar.
        /// </summary>
        /// <param name="spriteBatch">
        /// The sprite batch.
        /// </param>
        /// <param name="radartexture">
        /// The radartexture.
        /// </param>
        public virtual void Drawradar(SpriteBatch spriteBatch, Texture2D radartexture)
        {
            var temprect = new Rectangle(0, 0, Settings.Default.ViewWidth, Settings.Default.RadarHeight);
            spriteBatch.Draw(radartexture, temprect, temprect, Color.White);
            var positionInradar =
                new Vector2(
                    (Position.X + Settings.Default.RadarHeight - (Settings.Default.ViewWidth / 2f)) / Game1.Level.Width *
                    Settings.Default.ViewWidth,
                    Position.Y / Game1.Level.Height / 20 * Settings.Default.ViewHeight - 1);
            spriteBatch.Draw(
                Texture, positionInradar, SourceRectangle, Color.White, Rotation, Center, 0.1f, IsFlip, 0.6f);
        }

        /// <summary>
        /// The update.
        /// </summary>
        /// <param name="gameTime">
        /// The game time.
        /// </param>
        public abstract void Update(GameTime gameTime);

        #endregion

        /// <summary>
        /// The collide.
        /// </summary>
        /// <param name="other">
        /// The other.
        /// </param>
        /// <returns>
        /// </returns>
        public virtual Vector2 Collide(BaseModel other)
        {
            return Procedures.IntersectPixels(
                CollisionMatrix,
                frameSize.X,
                frameSize.Y,
                Texturedata,
                other.CollisionMatrix,
                other.frameSize.X,
                other.frameSize.Y,
                other.Texturedata);
        }
    }
}